#pragma once
#include "../logger.hpp"
#include "chat_session_member.hxx"
#include "chat_session_member-odb.hxx"
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <memory>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include <sstream>
#include <string>
#include <vector>

namespace shared {

namespace dal {

class ChatSessionMemberDao;
using ChatSessionMemberDaoPtr = std::shared_ptr<ChatSessionMemberDao>;

class ChatSessionMemberDao
{
    using query = odb::query<entity::ChatSessionMember>;
    using QueryMaker = std::function<query(const std::string&, const std::string&)>;
public:
    ChatSessionMemberDao(const std::shared_ptr<odb::mysql::database>& db) : db_(db) {}
    // 一次新增单成员(适用于群聊拉人)
    bool insert(const std::string& sessionId, const std::string& userId)
    {
        try {
            odb::transaction trans(db_->begin());
            entity::ChatSessionMember csm(sessionId, userId);
            db_->persist(csm);
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("向会话({})新增用户({})失败: {}", sessionId, userId, e.what());
            return false;
        }
        return true;
    }
    // 一次新增多成员(适用于新好友的会话创建 && 群聊创建)
    bool insert(const std::pair<std::string, std::vector<std::string>>& memberList)
    {
        try {
            odb::transaction trans(db_->begin());
            for(auto& userId : memberList.second) {
                entity::ChatSessionMember csm(memberList.first, userId);
                db_->persist(csm);
            }
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("向会话({})新增多用户失败: {}", memberList.first, e.what());
            return false;
        }
        return true;
    }
    // 删除指定会话中的指定成员
    bool remove(entity::ChatSessionMember& chatSessionMember)
    {
        return removeChatSessionMember(chatSessionMember.sessionId(), chatSessionMember.userId(), 
            [&](const std::string& sessionId, const std::string& userId) {
                return query::sessionId == sessionId && query::userId == userId; 
            }
        );
    }
    // 删除指定会话所有成员
    bool remove(const std::string& sessionId)
    {
        return removeChatSessionMember(sessionId, "all-user", 
            [&](const std::string& sessionId, const std::string& userId) {
                return query::sessionId == sessionId; 
            }
        );
    }
    // 获取指定会话的所有成员
    std::vector<std::string> selectMembers(const std::string& sessionId)
    {
        std::vector<std::string> res;
            try {
                odb::transaction trans(db_->begin());
                typedef odb::result<entity::ChatSessionMember> result;
                result ret(db_->query<entity::ChatSessionMember>(query::sessionId == sessionId));
                for (auto it = ret.begin(); it != ret.end(); ++it) {
                    res.push_back(it->userId());
                }
                trans.commit();
            } catch (const std::exception& e) {
                LOG_ERROR("获取会话成员({})失败: {}", sessionId, e.what());
        }
        return res;
    }
private:
    bool removeChatSessionMember(const std::string& val1, const std::string& val2, const QueryMaker& queryMaker) 
    {
        try {
            odb::transaction trans(db_->begin());
            db_->erase_query<entity::ChatSessionMember>(queryMaker(val1, val2));
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("删除会话({})成员({})失败: {}", val1, val2, e.what());
            return false;
        }
        return true;
    }

private:
    std::shared_ptr<odb::mysql::database> db_;
};


}}